package org.example.chinesedays.utils;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;

public class HolidayFetcher {

    private static final CloseableHttpClient httpClient;

    static {
        try {
            // 创建信任所有证书的 SSL 上下文
            SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, (TrustStrategy) (chain, authType) -> true).build();

            SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);

            httpClient = HttpClients.custom().setSSLSocketFactory(sslSocketFactory).build();
        } catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) {
            throw new RuntimeException("创建http失败", e);
        }
    }

    private static final Gson gson = new Gson();

    // 根据年份获取所有假期文档的 URL
    public static List<String> getPaperUrls(int year) throws IOException {
        List<String> urls = new ArrayList<>();
        int pageIndex = 0;
        boolean hasNextPage = true;
        String baseUrl = "https://sousuo.www.gov.cn/search-gov/data";

        try {
            while (hasNextPage) {
                // 构建带参数的 URI
                URI uri = new URIBuilder(baseUrl).addParameter("t", "zhengcelibrary_gw").addParameter("p", String.valueOf(pageIndex)).addParameter("n", "5").addParameter("q", "假期 " + year).addParameter("pcodeJiguan", "国办发明电").addParameter("puborg", "国务院办公厅").addParameter("filetype", "通知").addParameter("sort", "pubtime").build();

                HttpGet request = new HttpGet(uri);

                try (CloseableHttpResponse response = httpClient.execute(request)) {
                    int statusCode = response.getStatusLine().getStatusCode();
                    if (statusCode != 200) {
                        throw new IOException("状态码 " + statusCode);
                    }

                    HttpEntity entity = response.getEntity();
                    String responseBody = EntityUtils.toString(entity, StandardCharsets.UTF_8);
                    JsonObject json = gson.fromJson(responseBody, JsonObject.class);

                    int code = json.get("code").getAsInt();
                    if (code == 1001) {
                        return urls;
                    }
                    if (code != 200) {
                        throw new IOException("Error: " + code + ": " + json.get("msg").getAsString());
                    }

                    JsonObject searchVO = json.getAsJsonObject("searchVO");
                    JsonArray listVO = searchVO.getAsJsonArray("listVO");
                    for (int i = 0; i < listVO.size(); i++) {
                        JsonObject item = listVO.get(i).getAsJsonObject();
                        String title = item.get("title").getAsString();
                        if (title.contains(String.valueOf(year))) {
                            urls.add(0, item.get("url").getAsString());
                        }
                    }
                    int totalPage = searchVO.get("totalpage").getAsInt();
                    pageIndex++;
                    hasNextPage = pageIndex < totalPage;
                }
            }
        } catch (Exception e) {
            throw new IOException("请求失败", e);
        }
        return urls;
    }

    // 根据单个URL抓取文档内容
    public static String getPaper(String url) throws IOException {
        HttpGet request = new HttpGet(url);

        try (CloseableHttpResponse response = httpClient.execute(request)) {
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                throw new IOException("请求失败，状态码 " + statusCode);
            }
            HttpEntity entity = response.getEntity();
            String html = EntityUtils.toString(entity, StandardCharsets.UTF_8);

            Document doc = Jsoup.parse(html);
            Element container = doc.getElementById("UCAP-CONTENT");
            if (container == null) {
                throw new IOException("获取数据失败: " + url);
            }

            String containerHtml = container.html().replaceAll("<br\\s*/?>", "</p><p>");
            Document frag = Jsoup.parse("<div>" + containerHtml + "</div>");
            Elements paragraphs = frag.select("p");
            StringBuilder sb = new StringBuilder();
            for (Element p : paragraphs) {
                String text = p.text().trim();
                if (!text.isEmpty()) {
                    sb.append(text).append("\n");
                }
            }
            String result = sb.toString().trim();
            if (result.isEmpty()) {
                throw new IOException(url);
            }
            return result;
        } catch (ClientProtocolException e) {
            throw new IOException(e);
        }
    }

    // 抓取所有文档并合并内容
    public static String fetchHoliday(int year) throws IOException, InterruptedException {
        List<String> paperUrls = getPaperUrls(year);
        StringBuilder papers = new StringBuilder();
        for (String url : paperUrls) {
            String paper = getPaper(url);
            papers.append(paper).append("\n");
        }
        return papers.toString().trim();
    }

}
